package cn.edu.ncut.cs.springboot.petmanagementsystem.service.Impl;

import cn.edu.ncut.cs.springboot.petmanagementsystem.mapper.*;
import cn.edu.ncut.cs.springboot.petmanagementsystem.pojo.*;
import cn.edu.ncut.cs.springboot.petmanagementsystem.service.StatisticsService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class StatisticsServiceImpl implements StatisticsService {

    @Autowired
    private PetMapper petMapper;
    
    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private ServiceReservationMapper reservationMapper;
    
    @Autowired
    private PetHealthRecordMapper healthRecordMapper;
    
    @Autowired
    private FavoriteMapper favoriteMapper;

    @Override
    public Map<String, Object> getUserStatistics(Long userId) {
        Map<String, Object> statistics = new HashMap<>();
        
        if (userId == null) {
            return statistics;
        }
        
        try {
            // 宠物数量
            LambdaQueryWrapper<Pet> petWrapper = new LambdaQueryWrapper<>();
            petWrapper.eq(Pet::getOwnerId, userId);
            Long petCount = petMapper.selectCount(petWrapper);
            statistics.put("petCount", petCount);
            
            // 订单统计
            LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
            orderWrapper.eq(Order::getUserId, userId);
            Long totalOrders = orderMapper.selectCount(orderWrapper);
            statistics.put("totalOrders", totalOrders);
            
            // 订单金额统计
            List<Order> orders = orderMapper.selectList(orderWrapper);
            double totalSpent = orders.stream()
                .filter(o -> o.getTotalAmount() != null)
                .mapToDouble(o -> o.getTotalAmount().doubleValue())
                .sum();
            statistics.put("totalSpent", Math.round(totalSpent * 100.0) / 100.0);
            
            // 按订单状态统计
            Map<Integer, Long> orderByStatus = orders.stream()
                .collect(Collectors.groupingBy(Order::getOrderStatus, Collectors.counting()));
            statistics.put("ordersByStatus", orderByStatus);
            
            // 服务预约统计
            LambdaQueryWrapper<ServiceReservation> reservationWrapper = new LambdaQueryWrapper<>();
            reservationWrapper.eq(ServiceReservation::getUserId, userId);
            Long reservationCount = reservationMapper.selectCount(reservationWrapper);
            statistics.put("reservationCount", reservationCount);
            
            // 收藏商品数量
            LambdaQueryWrapper<Favorite> favoriteWrapper = new LambdaQueryWrapper<>();
            favoriteWrapper.eq(Favorite::getUserId, userId);
            Long favoriteCount = favoriteMapper.selectCount(favoriteWrapper);
            statistics.put("favoriteCount", favoriteCount);
            
            // 健康记录总数
            if (petCount > 0) {
                List<Pet> pets = petMapper.selectList(petWrapper);
                List<Long> petIds = pets.stream().map(Pet::getId).collect(Collectors.toList());
                
                LambdaQueryWrapper<PetHealthRecord> healthWrapper = new LambdaQueryWrapper<>();
                healthWrapper.in(PetHealthRecord::getPetId, petIds);
                Long healthRecordCount = healthRecordMapper.selectCount(healthWrapper);
                statistics.put("healthRecordCount", healthRecordCount);
            } else {
                statistics.put("healthRecordCount", 0);
            }
            
            // 最近30天活跃度
            LocalDateTime thirtyDaysAgo = LocalDateTime.now().minusDays(30);
            long recentOrders = orders.stream()
                .filter(o -> o.getCreateTime() != null && o.getCreateTime().isAfter(thirtyDaysAgo))
                .count();
            statistics.put("recentActivity", recentOrders);
            
            // 会员等级（简化实现）
            String memberLevel = "普通会员";
            if (totalSpent > 10000) {
                memberLevel = "钻石会员";
            } else if (totalSpent > 5000) {
                memberLevel = "黄金会员";
            } else if (totalSpent > 1000) {
                memberLevel = "白银会员";
            }
            statistics.put("memberLevel", memberLevel);
            
            // 注册天数（需要用户创建时间，这里简化）
            statistics.put("registrationDays", 30);
            
        } catch (Exception e) {
            log.error("获取用户统计失败", e);
        }
        
        return statistics;
    }

    @Override
    public Map<String, Object> getHealthTrend(Long petId, Integer months) {
        Map<String, Object> trend = new HashMap<>();
        
        if (petId == null) {
            return trend;
        }
        
        if (months == null || months <= 0) {
            months = 6; // 默认6个月
        }
        
        try {
            LocalDate startDate = LocalDate.now().minusMonths(months);
            
            // 查询时间范围内的健康记录
            LambdaQueryWrapper<PetHealthRecord> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PetHealthRecord::getPetId, petId);
            wrapper.ge(PetHealthRecord::getCheckDate, startDate);
            wrapper.orderByAsc(PetHealthRecord::getCheckDate);
            List<PetHealthRecord> records = healthRecordMapper.selectList(wrapper);
            
            trend.put("petId", petId);
            trend.put("months", months);
            trend.put("recordCount", records.size());
            
            // 按月份统计记录数量
            Map<String, Long> recordsByMonth = records.stream()
                .collect(Collectors.groupingBy(
                    r -> r.getCheckDate().getYear() + "-" + String.format("%02d", r.getCheckDate().getMonthValue()),
                    Collectors.counting()
                ));
            trend.put("recordsByMonth", recordsByMonth);
            
            // 按记录类型统计
            Map<String, Long> recordsByType = records.stream()
                .collect(Collectors.groupingBy(
                    r -> r.getRecordType() != null ? r.getRecordType() : "未分类",
                    Collectors.counting()
                ));
            trend.put("recordsByType", recordsByType);
            
            // 费用趋势
            List<Map<String, Object>> costTrend = records.stream()
                .filter(r -> r.getCost() != null && r.getCost().doubleValue() > 0)
                .map(r -> {
                    Map<String, Object> point = new HashMap<>();
                    point.put("date", r.getCheckDate());
                    point.put("cost", r.getCost());
                    point.put("type", r.getRecordType() != null ? r.getRecordType() : "未分类");
                    return point;
                })
                .collect(Collectors.toList());
            trend.put("costTrend", costTrend);
            
            // 总费用
            double totalCost = records.stream()
                .filter(r -> r.getCost() != null)
                .mapToDouble(r -> r.getCost().doubleValue())
                .sum();
            trend.put("totalCost", Math.round(totalCost * 100.0) / 100.0);
            
            // 平均每月费用
            double avgMonthlyCost = records.size() > 0 ? totalCost / months : 0;
            trend.put("avgMonthlyCost", Math.round(avgMonthlyCost * 100.0) / 100.0);
            
            // 健康评分（简化算法：基于检查频率和记录类型）
            int healthScore = 100;
            if (records.size() == 0) {
                healthScore = 60;
            } else if (records.size() < months / 2) {
                healthScore = 75;
            } else {
                healthScore = 90;
            }
            trend.put("healthScore", healthScore);
            
            // 建议
            List<String> suggestions = new ArrayList<>();
            if (records.size() == 0) {
                suggestions.add("建议进行首次健康检查");
            } else if (records.size() < months / 2) {
                suggestions.add("建议增加健康检查频率");
            }
            
            LocalDate lastCheck = records.isEmpty() ? null : records.get(records.size() - 1).getCheckDate();
            if (lastCheck != null && lastCheck.isBefore(LocalDate.now().minusMonths(3))) {
                suggestions.add("距离上次检查已超过3个月，建议复查");
            }
            
            trend.put("suggestions", suggestions);
            
        } catch (Exception e) {
            log.error("获取健康趋势失败", e);
        }
        
        return trend;
    }
}
